---
sidebar_position: 2
title: Why Hyper Fetch is Unique
sidebar_label: Comparison
---

import Tippy from "@tippyjs/react";
import "tippy.js/dist/tippy.css";

# Comparison

The biggest difference between **`Hyper Fetch`** and other libraries is the opinionated architecture and assumptions on
which it is built. Hyper Fetch’s core features are written in TS **without dependencies**; because of this, it can work
in many environments without a specific connection to a given framework.

Hyper Fetch is not just a wrapper; it offers full control over the flow and observation of data exchange. Our main goals
were to introduce:

- a data storage standard,
- offer an embedded HTTP adapter,
- reduce setup times,
- solve major architectural difficulties.

:::info

Producing an accurate and unbiased comparison is quite a challenge. Libraries develop quickly, so if you notice that our
data needs to be corrected, please let us know by opening an issue.

:::

---

## Why Hyper Fetch Is Unique

- Easy upload/download progress and ETA tracking
- Supports request queueing and many [dispatching strategies](/documentation/02-core/dispatcher.mdx#dispatching-modes)!
- [Command](/documentation/02-core/request.mdx) / [Builder](/documentation/02-core/client.mdx) pattern gives you amazing
  control over requests at any time
- Code-sharing architecture lets [testers to hook into development setup and types](/documentation/01-getting-started/testing.mdx)
- Features flat side-effects [helper hooks annotation](/documentation/04-react/01-overview.mdx#helper-hooks) and
  promotes readable code
- Provides structure [recipes](/documentation/01-getting-started/development.mdx#structure) for large scale applications
  that significantly limit maintenance costs.
- Core features include [offline](/guides/02-advanced/offline.mdx) and
  [persistence](/guides/02-advanced/persistence.mdx) support, giving you full control over your data

---

## Features

<div>✅ - Documented support</div>
<div>🚧 - Work in progress</div>
<div>🔵 - Require additional Plugin/Coding</div>
<div>🔴 - Not supported / Not documented</div>

<br />
<br />

<div className="comparison-table">
  <table>
    <thead>
      <tr>
        <th></th>
        <th>Hyper Fetch</th>
        <th>
          <a href="https://tanstack.com/query/v4/?from=reactQueryV3&original=https://react-query-v3.tanstack.com/">
            Query
          </a>
        </th>
        <th>
          <a href="https://swr.vercel.app/">SWR</a>
        </th>
        <th>
          <a href="https://www.apollographql.com/documentation/04-react/">Apollo</a>
        </th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>Supported environments</td>
        <td>Any</td>
        <td>Any</td>
        <td>React</td>
        <td>Any</td>
      </tr>
      <tr>
        <td>Protocols</td>
        <td>Any</td>
        <td>Any</td>
        <td>Any</td>
        <td>GraphQL</td>
      </tr>
      <tr>
        <td>Caching Approach</td>
        <td>Request Schema</td>
        <td>Hierarchical Key > Value</td>
        <td>Unique Key > Value</td>
        <td>Normalized Schema</td>
      </tr>
      <tr>
        <td>Cache Key Strategy</td>
        <td>Request Key</td>
        <td>JSON</td>
        <td>JSON</td>
        <td>GraphQL Query</td>
      </tr>
      <tr>
        <td>Data Change Detection</td>
        <td>Deep Comparison</td>
        <td>Deep Comparison</td>
        <td>Deep Comparison</td>
        <td>Deep Comparison</td>
      </tr>
      <tr>
        <td>Data Memoization</td>
        <td>Normalized Identity</td>
        <td>Full Structural Sharing</td>
        <td>Identity</td>
        <td>Normalized Identity</td>
      </tr>
      <tr>
        <td>Queue Key Strategy</td>
        <td>Request Key</td>
        <td>N/A</td>
        <td>N/A</td>
        <td>N/A</td>
      </tr>
      <tr>
        <td>Devtools</td>
        <td>✅</td>
        <td>✅</td>
        <td>🔵</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          Server Connection Setup{" "}
          <Tippy content="Being able to prepare global setup for server connection">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔵</td>
        <td>🔵</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          Shared Request{" "}
          <Tippy content="Being able to prepare requests to be reused in the application">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔵</td>
        <td>🔵</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          Dependency tracking{" "}
          <Tippy content="It allows to limit re-rendering only to the dependent key changes">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>Cache Persistence</td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          Requests Persistence{" "}
          <Tippy content="Possibility to keep data prepared for request in persistent storage and resend it on new session">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔴</td>
        <td>🔴</td>
        <td>🔴</td>
      </tr>
      <tr>
        <td>
          Download ETA{" "}
          <Tippy content="Tracking of the download progress to being able to access size left and time ETA">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅ </td>
        <td>🔵</td>
        <td>🔵</td>
        <td>🔵</td>
      </tr>
      <tr>
        <td>
          Uploading ETA{" "}
          <Tippy content="Tracking of the upload progress to being able to access size left and time ETA">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔵</td>
        <td>🔵</td>
        <td>🔵</td>
      </tr>
      <tr>
        <td>
          Pooling{" "}
          <Tippy content="Fetch new data at interval">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          Dependent Queries{" "}
          <Tippy content="Being able to hold on one request until another is finished">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>Paginated Queries</td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          Query Params Parsing{" "}
          <Tippy content="Built-in query parsing from object or string">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔵</td>
        <td>🔵</td>
        <td>🔵</td>
      </tr>
      <tr>
        <td>
          Queueing{" "}
          <Tippy content="Allows to group requests in queues and control sending process">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔴</td>
        <td>🔴</td>
        <td>🔴</td>
      </tr>
      <tr>
        <td>
          Retries{" "}
          <Tippy content="When request fails try again to trigger it">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
        <td>🔵</td>
      </tr>
      <tr>
        <td>
          Default Adapter{" "}
          <Tippy content="Library includes prepared adapter for requesting">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔴</td>
        <td>🔴</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          Infinite Queries{" "}
          <Tippy content="When we want to dynamically 'load more' content on the list">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          SSR{" "}
          <Tippy content="Server Side Rendering">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          Initial Data{" "}
          <Tippy content="Initialize with prepared placeholder data">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          Cache Hydration{" "}
          <Tippy content="Allows to hydrate cache storage with data from other sources">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅ </td>
        <td>✅ </td>
        <td>🔴</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          Garbage Collecting{" "}
          <Tippy content="Stale data gets removed from memory">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>✅</td>
        <td>🔴</td>
        <td>🔴</td>
      </tr>
      <tr>
        <td>
          Pre Request Intercepting{" "}
          <Tippy content="Intercept and modify every request before being triggered">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔵</td>
        <td>🔵</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          Post Request Intercepting{" "}
          <Tippy content="Intercept and modify every response before being saved and emitted">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔵</td>
        <td>🔵</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          Prefetching{" "}
          <Tippy content="Prefetch your data before your components being mounted">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>✅</td>
        <td>🔵</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          Cancellation{" "}
          <Tippy content="Cancel ongoing request">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>✅</td>
        <td>🔴</td>
        <td>🔴</td>
      </tr>
      <tr>
        <td>
          Queue Cancellation{" "}
          <Tippy content="Cancel group of ongoing requests by their queue key">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔴</td>
        <td>🔴</td>
        <td>🔴</td>
      </tr>
      <tr>
        <td>
          Authentication{" "}
          <Tippy content="Has built-in solutions for authentication like intercepting and possibilities to turn on/off">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔵</td>
        <td>🔵</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          Stale While Revalidate{" "}
          <Tippy content="Load cache data and refresh it in background">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>Refresh Data</td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          Offline Request Pause{" "}
          <Tippy content="When app goes offline, it waits until connection is back and retries paused requests">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>✅</td>
        <td>🔴</td>
        <td>🔴</td>
      </tr>
      <tr>
        <td>
          Network Status Re-fetching{" "}
          <Tippy content="Trigger re-fetch when your app goes online">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          Window Focus Re-fetching{" "}
          <Tippy content="Trigger re-fetch when you switch tabs or windows">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
        <td>🔴</td>
      </tr>
      <tr>
        <td>
          Normalized Caching{" "}
          <Tippy content="Storing cached data in flat architecture to prevent duplication">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔴</td>
        <td>🔴</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          Automatic Re-fetch After Mutation{" "}
          <Tippy content="Refresh cache data once you post mutation request">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔵</td>
        <td>🔵</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          Query Matching{" "}
          <Tippy content="Make operations on queued queries by their keys - you can cancel, stop or delete them from queue.">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>✅</td>
        <td>🔴</td>
        <td>🔴</td>
      </tr>
      <tr>
        <td>
          Cache Matching{" "}
          <Tippy content="Make operations on queries by their keys. Re-fetch groups of requests with partial names/regex or full keys.">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          Query Lifecycle Events{" "}
          <Tippy content="Receive every lifecycle response for any request. Request start, progress, response start, success, error, finished.">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔴</td>
        <td>🔴</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          Data Flow Standard{" "}
          <Tippy content="Having standardized format for data exchange and for easy reading/dumping">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔴</td>
        <td>🔴</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          Request Start/Stop{" "}
          <Tippy content="Possibility to control particular request in a queue.">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔴</td>
        <td>🔴</td>
        <td>🔴</td>
      </tr>
      <tr>
        <td>
          Request Queue Start/Stop/Pause{" "}
          <Tippy content="Possibility to control all queued requests.">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔴</td>
        <td>🔴</td>
        <td>🔴</td>
      </tr>
      <tr>
        <td>
          Request Data Mapping{" "}
          <Tippy content="Before we send a request we can map the data it's transferring to different format before it gets to server">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔵</td>
        <td>🔵</td>
        <td>N/A</td>
      </tr>
      <tr>
        <td>
          Cache Invalidation{" "}
          <Tippy content="Invalidate cache data to re-fetch it.">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          File Uploading{" "}
          <Tippy content="File upload with built-in adapter">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔵</td>
        <td>🔵</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          Global Response Side-Effects{" "}
          <Tippy content="We can hook global listeners on a particular request to listen and trigger side effects while it's being send">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔴</td>
        <td>🔴</td>
        <td>🔴</td>
      </tr>
      <tr>
        <td>
          Scroll Recovery{" "}
          <Tippy content="Going back to previous cache will restore scroll as data will be imminently shown to the user.">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          Simple Request Execution{" "}
          <Tippy content="Possibility to trigger requests requests">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔴</td>
        <td>🔴</td>
        <td>🔴</td>
      </tr>
      <tr>
        <td>
          Requests Manager{" "}
          <Tippy content="Possibility to show requests being uploaded throughout the whole system. Works like uploading managers, but much more advanced.">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔴</td>
        <td>🔴</td>
        <td>🔴</td>
      </tr>
      <tr>
        <td>
          Tabs Storages Synchronization{" "}
          <Tippy content="Being able to synchronize tabs data">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>🚧</td>
        <td>🚧</td>
        <td>🔴</td>
        <td>🔴</td>
      </tr>
      <tr>
        <td>
          Tabs Dispatching Synchronization{" "}
          <Tippy content="Being able to synchronize not sent queries queues between tabs which is required to present full persistence in browser">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>🚧</td>
        <td>🔴</td>
        <td>🔴</td>
        <td>🔴</td>
      </tr>
      <tr>
        <td>
          Websocket{" "}
          <Tippy content="Being able to listen and emit events">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔴</td>
        <td>🔴</td>
        <td>🔴</td>
      </tr>
      <tr>
        <td>
          Server Sent Events{" "}
          <Tippy content="Being able to listen to server sent events">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔴</td>
        <td>🔴</td>
        <td>🔴</td>
      </tr>
    </tbody>
  </table>
</div>

---

## Typescript features

<div className="comparison-table">
  <table>
    <thead>
      <tr>
        <th></th>
        <th>Hyper Fetch</th>
        <th>
          <a href="https://tanstack.com/query/v4/?from=reactQueryV3&original=https://react-query-v3.tanstack.com/">
            Query
          </a>
        </th>
        <th>
          <a href="https://swr.vercel.app/">SWR</a>
        </th>
        <th>
          <a href="https://www.apollographql.com/documentation/04-react/">Apollo</a>
        </th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>
          Response types{" "}
          <Tippy content="What data type you expect to receive from server">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          Request data types{" "}
          <Tippy content="Pass the type to specify the data schema to be send">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          Global error types{" "}
          <Tippy content="Specify possible error responses for all requests in the system">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔴</td>
        <td>🔴</td>
        <td>🔴</td>
      </tr>
      <tr>
        <td>
          Local error types{" "}
          <Tippy content="Being able to specify particular endpoint errors apart from global error type">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔴</td>
        <td>🔴</td>
        <td>🔴</td>
      </tr>
      <tr>
        <td>
          Query params types{" "}
          <Tippy content="Being able to pass type checking for endpoint query params">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔴</td>
        <td>🔴</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          Params types{" "}
          <Tippy content="Being able to automatically track the record of endpoint string">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔴</td>
        <td>🔴</td>
        <td>✅</td>
      </tr>
      <tr>
        <td>
          Request state tracking types{" "}
          <Tippy content="Types to check if you already set the data/params/query params on given request to prevent data corruption">
            <span>ℹ️</span>
          </Tippy>
        </td>
        <td>✅</td>
        <td>🔴</td>
        <td>🔴</td>
        <td>✅</td>
      </tr>
    </tbody>
  </table>
</div>
